<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button class="start">按钮开始</button>
    <button class="end">按钮结束</button>
    <script>
      //1. 自定义实现window.alert()
      window.alert = function (msg) {
        // 创建一个iframe标签
        const iframe = document.createElement('iframe')
        // 将iframe挂载到浏览器页面上，获取浏览器window
        document.body.appendChild(iframe)
        const iwindow = iframe.contentWindow
        iwindow.alert(msg)
      }
      // window.alert(23323232)

      //2.  自定义实现一个new 方法
      // 一定要传参函数
      function myNew(fn, ...rest) {
        // 1. 创建一个对象
        const obj = Object.create(fn.prototype) 
        const result = fn.call(obj, ...rest)
        return typeof restult === 'object' ? result : obj
      }
      function Person(name, age) {
        this.name = name
        this.age = age
      }
      console.log(new Person('zhangsan', 18))
      console.log(myNew(Person, 'zhangsan', 18))
      
      // 3. 实现一个函数颗粒化
      // sum(5)(6)
      // 实现一个中间件
      class Middleware{
        constructor() {
          this.middlewares = []
        }
        use(fn) {
          if(typeof fn !== 'function'){
            throw new Error('params must be a function')
          }
          this.middlewares.push(fn)
          return this
        }
        compose() {
          const middlewares = this.middlewares
          return dispatch(0)
          function dispatch(index) {
            const middleware = middlewares[index]
            if(!middleware) return
            try{
              const result = middleware({}, dispatch.bind(null, index + 1))
              Promise.resolve(result)
            }catch(e) {
              console.log(e.error)
              Promise.reject(e.error)
            }
          }
        }
      }
      // 使用
      const middleware = new Middleware()
      middleware.use(async (ctx, next) => {
        console.log(1)
        const resu = await next()
        console.log(resu)
        console.log(2)
        return Promise.resolve(5)
      })
      middleware.use(async (ctx, next) => {
        console.log(3)
        await next()
        console.log(4)
        return Promise.resolve(6)
      })
      middleware.compose()
    </script>
  </body>
</html>
